package com.vehicle.biz.Impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.vehicle.biz.TransportVehicleBiz;
import com.vehicle.biz.event.VehicleChangeEvent;
import com.vehicle.domains.bo.QueryCommonVehicleBo;
import com.vehicle.domains.bo.QueryTransportVehicleBo;
import com.vehicle.domains.entity.CommonVehicleEntity;
import com.vehicle.domains.entity.TransportVehicleEntity;
import com.vehicle.domains.vo.BasePage;
import com.vehicle.domains.vo.req.vehicle.AddTransportVehicleReq;
import com.vehicle.domains.vo.req.vehicle.TransportVehicleListReq;
import com.vehicle.domains.vo.req.vehicle.UpdateTransportVehicleReq;
import com.vehicle.domains.vo.res.vehicle.TransportVehicleRes;
import com.vehicle.enums.GovUploadStatus;
import com.vehicle.enums.VehicleTypeEnum;
import com.vehicle.exception.VehicleAccessException;
import com.vehicle.service.CommonVehicleService;
import com.vehicle.service.TransportVehicleService;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class TransportVehicleBizImpl implements TransportVehicleBiz {

    @Resource
    private TransportVehicleService transportVehicleService;

    @Resource
    private CommonVehicleService commonVehicleService;

    @Resource
    private ApplicationEventPublisher publisher;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addTransportVehicle(AddTransportVehicleReq req) {
        TransportVehicleEntity transportVehicleEntity = new TransportVehicleEntity();
        BeanUtils.copyProperties(req, transportVehicleEntity);
        //设置车辆上传状态
        transportVehicleEntity.setGovUploadStatus(GovUploadStatus.INIT.name());
        transportVehicleService.addTransportVehicle(transportVehicleEntity);
        //同步普通车辆信息
        CommonVehicleEntity commonVehicleEntity = new CommonVehicleEntity();
        BeanUtils.copyProperties(req, commonVehicleEntity);
        commonVehicleEntity.setVehicleType(VehicleTypeEnum.TRANSPORT.name());
        commonVehicleEntity.setAssociationId(transportVehicleEntity.getId());
        commonVehicleService.addCommonVehicle(commonVehicleEntity);

        VehicleChangeEvent vehicleChangeEvent = new VehicleChangeEvent(this,commonVehicleEntity.getId());
        publisher.publishEvent(vehicleChangeEvent);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateTransportVehicle(UpdateTransportVehicleReq req) {
        checkTransportVehicleExist(req.getId());
        TransportVehicleEntity updateTransportEntity = new TransportVehicleEntity();
        BeanUtils.copyProperties(req, updateTransportEntity);
        transportVehicleService.updateTransportVehicle(updateTransportEntity);

        CommonVehicleEntity commonVehicleEntity = checkCommonVehicleExist(req.getId());
        CommonVehicleEntity updateCommonEntity = new CommonVehicleEntity();
        BeanUtils.copyProperties(req, updateCommonEntity);
        updateCommonEntity.setId(commonVehicleEntity.getId());
        commonVehicleService.updateCommonVehicle(updateCommonEntity);
        VehicleChangeEvent vehicleChangeEvent = new VehicleChangeEvent(this,commonVehicleEntity.getId());
        publisher.publishEvent(vehicleChangeEvent);
    }

    @Override
    public void deleteTransportVehicle(Long id) {
        checkTransportVehicleExist(id);
        CommonVehicleEntity commonVehicleEntity = checkCommonVehicleExist(id);
        commonVehicleService.deleteCommonVehicle(commonVehicleEntity.getId());
        transportVehicleService.deleteTransportVehicle(id);
    }

    @Override
    public TransportVehicleRes getTransportVehicleById(Long id) {
        TransportVehicleEntity transportVehicleEntity = checkTransportVehicleExist(id);
        TransportVehicleRes transportVehicleRes = new TransportVehicleRes();
        BeanUtils.copyProperties(transportVehicleEntity, transportVehicleRes);
        CommonVehicleEntity commonVehicleEntity = checkCommonVehicleExist(id);
        //合并普通车辆信息和运输车辆信息
        BeanUtils.copyProperties(commonVehicleEntity, transportVehicleRes);
        return transportVehicleRes;
    }

    @Override
    public BasePage<TransportVehicleRes> listTransportVehicles(TransportVehicleListReq req) {
        Page<TransportVehicleEntity> page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        QueryTransportVehicleBo queryTransportVehicleBo = new QueryTransportVehicleBo();
        BeanUtils.copyProperties(req, queryTransportVehicleBo);
        List<TransportVehicleEntity> transportVehicleEntityList = transportVehicleService.selectTransportVehicleList(queryTransportVehicleBo);
        List<Long> ids = transportVehicleEntityList.stream().map(TransportVehicleEntity::getId).toList();
        QueryCommonVehicleBo queryCommonVehicleBo = new QueryCommonVehicleBo();
        queryCommonVehicleBo.setAssIds(ids);
        List<CommonVehicleEntity> commonVehicleEntityList = commonVehicleService.selectCommonVehicleList(queryCommonVehicleBo);
        //过滤出运输车辆
        commonVehicleEntityList = commonVehicleEntityList.stream().filter(commonVehicleEntity -> commonVehicleEntity.getVehicleType().equals(VehicleTypeEnum.TRANSPORT.name())).toList();
        Map<Long, List<CommonVehicleEntity>> collect = commonVehicleEntityList.stream().collect(Collectors.groupingBy(CommonVehicleEntity::getAssociationId));
        List<TransportVehicleRes> list = transportVehicleEntityList.stream().map(new Function<TransportVehicleEntity, TransportVehicleRes>() {
            @Override
            public TransportVehicleRes apply(TransportVehicleEntity transportVehicleEntity) {
                TransportVehicleRes transportVehicleRes = new TransportVehicleRes();
                BeanUtils.copyProperties(transportVehicleEntity, transportVehicleRes);
                CommonVehicleEntity commonVehicleEntity = collect.get(transportVehicleEntity.getId()).get(0);
                BeanUtils.copyProperties(commonVehicleEntity, transportVehicleRes);
                return transportVehicleRes;
            }
        }).toList();
        return BasePage.generateResult(page.getTotal(), page.getPages(), list);
    }

    private TransportVehicleEntity checkTransportVehicleExist(Long id) {
        TransportVehicleEntity transportVehicleEntity = transportVehicleService.getTransportVehicleById(id);

        if (transportVehicleEntity == null) {
            throw VehicleAccessException.DATA_NOT_EXIST.newInstance("车辆不存在");
        }

        return transportVehicleEntity;
    }

    private CommonVehicleEntity checkCommonVehicleExist(Long id) {
        CommonVehicleEntity commonVehicleEntity = commonVehicleService.getCommonVehicleByAssociationId(id);

        if (commonVehicleEntity == null) {
            throw VehicleAccessException.DATA_NOT_EXIST.newInstance("车辆不存在");
        }

        return commonVehicleEntity;
    }
}
